<template>
  <view class="view-bg container">
    <nav-bar title="蓝牙"></nav-bar>

    <button type="primary" @click="initBluetooth">初始化蓝牙</button>
    <button :disabled="!bluetoothEnabled" type="primary" @click="startScan">搜索设备</button>

    <view v-if="devices.length" class="device-list">
      <view v-for="(item, index) in devices" :key="index" @click="connectDevice(item)">
        {{ item.name || '未知设备' }} ({{ item.deviceId }})
      </view>
    </view>

    <view v-if="connectedDevice">
      <text>已连接: {{ connectedDevice.name }}</text>
      <button @click="getServices">获取服务</button>
      <button @click="onClose">关闭连接</button>
      <button @click="writeValue">写数据</button>
      <button @click="readValue">读数据</button>
    </view>
  </view>
</template>

<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { ref } from 'vue';
import { processWeightData } from './blue';

const bluetoothEnabled = ref(false);
const devices = ref([]);
const connectedDevice = ref(null);
const services = ref([]);

onLoad(() => {
  console.clear();

  const bluetoothData = [
    32, 2, 25, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 180
  ];
  const result = processWeightData(bluetoothData);
  console.table(result);
});

// 初始化蓝牙适配器
const initBluetooth = () => {
  uni.openBluetoothAdapter({
    success: res => {
      bluetoothEnabled.value = true;
      uni.showToast({
        title: '蓝牙初始化成功'
      });
      checkBluetoothState();
    },
    fail: err => {
      console.error('初始化失败:', err);
      if (err.errCode === 10001) {
        uni.showModal({
          content: '请开启手机蓝牙'
        });
      }
    }
  });
};

// 检查蓝牙状态
const checkBluetoothState = () => {
  uni.getBluetoothAdapterState({
    success: res => {
      if (!res.available) {
        uni.showModal({
          content: '蓝牙不可用'
        });
      }
    }
  });
};

// 关闭连接
const onClose = () => {
  uni.closeBLEConnection({
    deviceId: connectedDevice.value.deviceId,
    serviceId: serviceId,
    success: res => {
      uni.showToast({
        title: '已关闭连接'
      });
    },
    fail: err => {
      console.error('关闭连接失败:', err);
    }
  });
};

// 开始扫描设备
const startScan = () => {
  uni.startBluetoothDevicesDiscovery({
    allowDuplicatesKey: false,
    success: res => {
      uni.showLoading({
        title: '搜索中...'
      });
      // 监听找到新设备事件
      uni.onBluetoothDeviceFound(res => {
        res.devices.forEach(item => {
          if (item.name && !devices.value.some(d => d.deviceId === item.deviceId)) {
            devices.value.push(item);
            // devices.value = item;
            if (item.name === 'Elfin_4DA0') {
              stopScan();
            }
          }
        });
      });
    }
  });
};

// 停止扫描
const stopScan = () => {
  uni.stopBluetoothDevicesDiscovery({
    success: () => {
      uni.hideLoading();
      // uni.offBluetoothDeviceFound();
    }
  });
};

// 连接设备
const connectDevice = device => {
  console.log('连接设备:', device.deviceId);
  uni.createBLEConnection({
    deviceId: device.deviceId,
    success: res => {
      connectedDevice.value = device;
      uni.showToast({
        title: '连接成功'
      });

      // 延迟获取服务
      setTimeout(() => {
        getServices();
      }, 1500);
    },
    fail: err => {
      console.error('连接失败:', err);
    }
  });
};

// 获取服务列表
const getServices = () => {
  uni.getBLEDeviceServices({
    deviceId: connectedDevice.value.deviceId,
    success: res => {
      console.log('获取服务列表:', res.services);
      services.value = res.services;
      getCharacteristics(); // 获取第一个服务的特征值
    }
  });
};

const serviceId = '0000fee7-0000-1000-8000-00805f9b34fb'; // 服务id
const notifyId = '0000FEC8-0000-1000-8000-00805F9B34FB'; // 特征值id
const writeId = '0000FED4-0000-1000-8000-00805F9B34FB'; // 写入数据的特征值id
const readId = '0000FED4-0000-1000-8000-00805F9B34FB'; // 读取数据的特征值id

// 获取特征值
const getCharacteristics = () => {
  uni.getBLEDeviceCharacteristics({
    deviceId: connectedDevice.value.deviceId,
    serviceId: serviceId,
    success: res => {
      console.log('获取特征值:', res.characteristics);
      // 监听特征值变化
      notifyCharacteristic();
    }
  });
  // notifyCharacteristic();
};

// 启用特征值通知
const notifyCharacteristic = () => {
  uni.notifyBLECharacteristicValueChange({
    deviceId: connectedDevice.value.deviceId,
    serviceId: serviceId,
    characteristicId: notifyId,
    state: true,
    success: () => {
      // console.log('启用通知成功');

      // 监听特征值变化
      setTimeout(() => {
        uni.onBLECharacteristicValueChange(res => {
          let arr = [];
          for (let i of res.value) {
            arr.push(i.toString());
          }
          console.log('监听的数据:', arr);
          // const result = processor.processWeightData(res.value);
          // console.log('处理后的数据:', result);

          const result = processWeightData(res.value);
          console.log('处理后的数据:', result);
        });
      }, 500);
    },
    fail: err => {
      console.error('启用通知失败:', err);
    }
  });
};

// 写数据
const writeValue = () => {
  uni.writeBLECharacteristicValue({
    deviceId: connectedDevice.value.deviceId,
    serviceId: serviceId,
    characteristicId: writeId,
    // value: uni.base64ToArrayBuffer('0103000000104406'),
    value: hexStringToArrayBuffer('0103000000104406'),
    writeType: 'write',
    success: () => {
      console.log('写入成功');
      readValue();
    },
    fail: err => {
      console.error('写入失败:', err);
    }
  });
};

// 十六进制字符串转ArrayBuffer
const hexStringToArrayBuffer = hexString => {
  const bytes = new Uint8Array(hexString.length / 2);
  for (let i = 0; i < hexString.length; i += 2) {
    bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);
  }
  return bytes.buffer;
};

// 读取数据
const readValue = () => {
  uni.readBLECharacteristicValue({
    deviceId: connectedDevice.value.deviceId,
    serviceId: serviceId,
    characteristicId: readId,
    success(res) {
      // console.log('读取数据成功');
    },
    fail(res) {
      // console.log('读取数据失败');
    }
  });
};

function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
    return ('00' + bit.toString(16)).slice(-2);
  });
  return hexArr.join('');
}
</script>

<style lang="scss" scoped>
.container {
  height: 100%;
  padding: 20px;
}

.device-list {
  margin-top: 20px;
  border-top: 1px solid #eee;
}

.device-list view {
  padding: 15px;
  border-bottom: 1px solid #eee;
}
</style>
